package com.leyou.item.service.Impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.leyou.common.utils.PageResult;
import com.leyou.item.bo.SpuBo;
import com.leyou.item.mapper.SkuMapper;
import com.leyou.item.mapper.SpuDetailMapper;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.mapper.StockMapper;
import com.leyou.item.pojo.Sku;
import com.leyou.item.pojo.Spu;
import com.leyou.item.pojo.SpuDetail;
import com.leyou.item.pojo.Stock;
import com.leyou.item.service.GoodsService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;


/**
 * Author: Saka
 * Date: 2019/1/20
 * Time: 19:00
 */
@Service
public class GoodsServiceImpl implements GoodsService{
    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private CategoryServiceImpl categoryService;
    @Autowired
    private BrandServiceImpl brandService;

    @Autowired
    private SpuDetailMapper spuDetailMapper;
    @Autowired
    private SkuMapper skuMapper;
    @Autowired
    private StockMapper stockMapper;

    @Override
    public PageResult<SpuBo> querySpuByPageAndSort(String key, Integer page, Integer rows, Boolean saleable,Boolean valid) {
        //分页
        PageHelper.startPage(page, rows);
        //创建查询条件
        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();

        if (StringUtils.isNotBlank(key)) {
            criteria.andLike("title", "%"+key+"%");
        }

        if (null != saleable) {
            criteria.andEqualTo("saleable", saleable);

        }
        if (null != valid) {
            criteria.andEqualTo("valid", valid);

        }


        //查询得到的是spu集合
        Page<Spu> spuPage = (Page<Spu>) this.spuMapper.selectByExample(example);
        //用来存放spubo的集合
        List<SpuBo> spuBoList = new ArrayList<>();
        spuPage.getResult().forEach(spu ->{//把spu集合转换成spubo集合
            SpuBo spuBo = new SpuBo();
            BeanUtils.copyProperties(spu, spuBo);

            //调用categoryService访问mapper
            List<String> names = categoryService.queryNamesByIds(Arrays.asList(spu.getCid1(),spu.getCid2(),spu.getCid3()));
            spuBo.setCname(StringUtils.join(names,"/"));
            spuBo.setBname(this.brandService.queryBrandById(spu.getBrandId()).getName());
            spuBoList.add(spuBo);


        });
        return new PageResult<>(spuPage.getTotal(),new Long(spuPage.getPages()),spuBoList);
    }


    @Transactional
    @Override
    public void saveGoods(SpuBo spuBo) {

        spuBo.setCreateTime(new Date());
        spuBo.setLastUpdateTime(spuBo.getCreateTime());
        spuBo.setSaleable(true);
        spuBo.setValid(true);
        //保存spu,回显id
        this.spuMapper.insertSelective(spuBo);
        //保存spu详情
        SpuDetail spuDetail = spuBo.getSpuDetail();
        spuDetail.setSpuId(spuBo.getId());

        this.spuDetailMapper.insertSelective(spuDetail);

        List<Sku> skuList = spuBo.getSkus();
        skuList.forEach(sku -> {
            sku.setSpuId(spuBo.getId());
            sku.setCreateTime(spuBo.getCreateTime());
            sku.setLastUpdateTime(spuBo.getLastUpdateTime());
            //保存sku
            this.skuMapper.insertSelective(sku);
            //保存sku,并且保存sku库存信息
            Stock stock = new Stock();
            stock.setSkuId(sku.getId());
            stock.setStock(sku.getStock());

            this.stockMapper.insertSelective(stock);
        });
    }

    @Override
    public SpuDetail querySpuDetailById(Long id) {
        return this.spuDetailMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<Sku> querySkuBySpuId(Long id) {
        Sku sku = new Sku();
        sku.setSpuId(id);
        List<Sku> skuList = this.skuMapper.select(sku);
        skuList.forEach(sku1 ->sku1.setStock(this.skuMapper.selectByPrimaryKey(sku1.getId()).getStock()));
        return skuList;
    }
    @Transactional
    @Override
    public void updateGoods(SpuBo spuBo) {
        //spu和spuDetail可以直接修改
        spuBo.setLastUpdateTime(new Date());//更新时间
        this.spuMapper.updateByPrimaryKeySelective(spuBo);

        this.spuDetailMapper.updateByPrimaryKeySelective(spuBo.getSpuDetail());
        //sku处理三种情况

        Sku record = new Sku();
        record.setSpuId(spuBo.getId());
        //数据库中以前和这个spu相关的所有sku
        List<Sku> dbSkus = this.skuMapper.select(record);

        List<Sku> toBeAdd = new ArrayList<>();
        List<Sku> toBeUpdate = new ArrayList<>();
        List<Sku> toBeDelete = new ArrayList<>();
        List<Sku> newSkus = spuBo.getSkus();
        newSkus.forEach(newSku->{//找出新增的sku,对其直接保存到数据库
            if (null == newSku.getId()) {

                newSku.setCreateTime(new Date());
                newSku.setLastUpdateTime(newSku.getCreateTime());
                newSku.setSpuId(spuBo.getId());

                this.skuMapper.insertSelective(newSku);
                //同时要保存库存
                Stock stock = new Stock();
                stock.setSkuId(newSku.getSpuId());
                stock.setStock(newSku.getStock());
                this.stockMapper.insertSelective(stock);
            } else {
                //如果id有值,直接进行修改操作,更改有两处,一处为sku,另一处为stock
                newSku.setLastUpdateTime(new Date());
                //因为id丢到了所以这里需要重新加id
                newSku.setSpuId(spuBo.getId());
                this.skuMapper.updateByPrimaryKeySelective(newSku);

                Stock stock = new Stock();
                stock.setSkuId(newSku.getSpuId());
                stock.setStock(newSku.getStock());
                this.stockMapper.updateByPrimaryKeySelective(stock);

                //相当于对dbskus做了迭代
                dbSkus.removeIf(obj->
                    obj.getId().equals(newSku.getId())
                );
            }

        });

        dbSkus.forEach(dbSku->{
            dbSku.setEnable(false);
            this.skuMapper.updateByPrimaryKeySelective(dbSku);
        });
    }

    @Override
    public void downShelves(Long id) {
        Spu spu = new Spu();
        spu.setId(id);
        spu.setSaleable(false);

        this.spuMapper.updateByPrimaryKeySelective(spu);

    }

    @Override
    public void onShelves(Long id) {
        Spu spu = new Spu();
        spu.setId(id);
        spu.setSaleable(true);

        this.spuMapper.updateByPrimaryKeySelective(spu);
    }

    @Override
    public void deleteShelves(Long id) {
        Spu spu = new Spu();
        spu.setId(id);
        spu.setValid(false);

        this.spuMapper.updateByPrimaryKeySelective(spu);
    }
}
